<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
	<title>histogram 聚合 | ElasticSearch 7.7 权威指南中文版</title>
	<meta name="keywords" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <meta name="description" content="ElasticSearch 权威指南中文版, elasticsearch 7, es7, 实时数据分析，实时数据检索" />
    <!-- Give IE8 a fighting chance -->
    <!--[if lt IE 9]>
    <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script>
    <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script>
    <![endif]-->
	<link rel="stylesheet" type="text/css" href="../static/styles.css" />
	<script>
	var _link = 'search-aggregations-bucket-histogram-aggregation.html';
    </script>
</head>
<body>
<div class="main-container">
    <section id="content">
        <div class="content-wrapper">
            <section id="guide" lang="zh_cn">
                <div class="container">
                    <div class="row">
                        <div class="col-xs-12 col-sm-8 col-md-8 guide-section">
                            <div style="color:gray; word-break: break-all; font-size:12px;">原英文版地址: <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-bucket-histogram-aggregation.html" rel="nofollow" target="_blank">https://www.elastic.co/guide/en/elasticsearch/reference/7.7/search-aggregations-bucket-histogram-aggregation.html</a>, 原文档版权归 www.elastic.co 所有<br/>本地英文版地址: <a href="../en/search-aggregations-bucket-histogram-aggregation.html" rel="nofollow" target="_blank">../en/search-aggregations-bucket-histogram-aggregation.html</a></div>
                        <!-- start body -->
                  <div class="page_header">
<strong>重要</strong>: 此版本不会发布额外的bug修复或文档更新。最新信息请参考 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html" rel="nofollow">当前版本文档</a>。
</div>
<div id="content">
<div class="breadcrumbs">
<span class="breadcrumb-link"><a href="index.html">Elasticsearch 权威指南 [7.7]</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations.html">聚合</a></span>
»
<span class="breadcrumb-link"><a href="search-aggregations-bucket.html">桶(bucket)聚合</a></span>
»
<span class="breadcrumb-node">histogram 聚合</span>
</div>
<div class="navheader">
<span class="prev">
<a href="search-aggregations-bucket-global-aggregation.html">« global 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-bucket-iprange-aggregation.html">ip_range 聚合 »</a>
</span>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h2 class="title">
<a id="search-aggregations-bucket-histogram-aggregation"></a>直方图(histogram)聚合<a class="edit_me edit_me_private" rel="nofollow" title="Editing on GitHub is available to Elastic" href="https://github.com/elastic/elasticsearch/edit/7.7/docs/reference/aggregations/bucket/histogram-aggregation.asciidoc">edit</a>
</h2>
</div></div></div>
<p>
一个基于值源(value source)的多桶聚合，可应用于从文档中提取的数值或数值范围值。

它根据值动态构建固定大小(也称为间隔/interval)的桶。

例如，如果文档有一个保存价格<code class="literal">price</code>(数字)的字段，我们可以配置这个聚合来动态构建间隔为<code class="literal">5</code>的桶(本例中是价格，则它可以表示5元)。

执行聚合时，将计算每个文档的 price 字段，并将其向下舍入到最接近的桶——例如，如果价格是<code class="literal">32</code>，桶大小是<code class="literal">5</code>，则舍入将得到<code class="literal">30</code>，因此该文档将“落入”与键<code class="literal">30</code>相关联的桶。

为了更正式，这里使用了舍入函数：
</p>
<div class="pre_wrapper lang-java">
<pre class="programlisting prettyprint lang-java">bucket_key = Math.floor((value - offset) / interval) * interval + offset</pre>
</div>
<p>
对于范围值，一个文档可能会落入多个桶。

第一个桶从范围的下限开始计算，计算方式与计算单个值的桶相同。

最后一个桶以相同的方式从范围的上限开始计算，范围计入这两个桶之间（含）的所有桶。
</p>
<p><code class="literal">interval</code>必须是正的小数，而<code class="literal">offset</code>必须是<code class="literal">[0, interval)</code>中的数(大于或等于<code class="literal">0</code>且小于<code class="literal">interval</code>的小数)</p>
<p>下面的代码片段根据<code class="literal">price</code>以<code class="literal">50</code>为间隔对产品进行“分桶”：</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/476.console"></div>
<p>响应可能如下所示：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "aggregations": {
        "prices" : {
            "buckets": [
                {
                    "key": 0.0,
                    "doc_count": 1
                },
                {
                    "key": 50.0,
                    "doc_count": 1
                },
                {
                    "key": 100.0,
                    "doc_count": 0
                },
                {
                    "key": 150.0,
                    "doc_count": 2
                },
                {
                    "key": 200.0,
                    "doc_count": 3
                }
            ]
        }
    }
}</pre>
</div>
<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_minimum_document_count"></a>最小文档数量
</h3>
</div></div></div>
<p>
上面的响应显示没有文档的 price 在<code class="literal">[100, 150)</code>范围内。

默认情况下，响应将用空桶填充直方图中的间隙。

得益于<code class="literal">min_doc_count</code>设置，可以更改和请求具有更高最小数量的桶：
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "min_doc_count" : 1
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/477.console"></div>
<p>响应：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "aggregations": {
        "prices" : {
            "buckets": [
                {
                    "key": 0.0,
                    "doc_count": 1
                },
                {
                    "key": 50.0,
                    "doc_count": 1
                },
                {
                    "key": 150.0,
                    "doc_count": 2
                },
                {
                    "key": 200.0,
                    "doc_count": 3
                }
            ]
        }
    }
}</pre>
</div>
<p><a id="search-aggregations-bucket-histogram-aggregation-extended-bounds"></a>
默认情况下，<code class="literal">histogram</code>返回数据本身范围内的所有桶，也就是说，具有最小值的文档(使用直方图)将确定最小桶(具有最小键的桶)，具有最大值的文档将确定最大桶(具有最大键的桶)。

通常，当请求空桶时，这会导致混乱，特别是当数据也被过滤时。
</p>
<p>为了理解其中的原因，我们来看一个例子：</p>
<p>
假设你正在过滤你的请求，以获取值在<code class="literal">0</code>到<code class="literal">500</code>之间的所有文档，此外，你希望使用间隔为<code class="literal">50</code>的直方图来分割每个价格的数据。

你还指定了<code class="literal">"min_doc_count" : 0</code>，因为你希望获得所有的桶，即使是空的桶。

如果碰巧所有产品(文档)的价格都高于 <code class="literal">100</code>，那么你将得到的第一个桶将是以<code class="literal">100</code>为键的桶。

这是令人困惑的，因为很多时候，你也想得到<code class="literal">0 - 100</code>之间的那些桶。
</p>
<p>
通过<code class="literal">extended_bounds</code>设置，你现在可以“强制” histogram 聚合开始根据特定的<code class="literal">min</code>值构建桶，并继续构建桶直到<code class="literal">max</code>值(即使不再有文档)。

仅当<code class="literal">min_doc_count</code>为 0 时，使用<code class="literal">extended_bounds</code>才有意义(如果<code class="literal">min_doc_count</code>大于0，则永远不会返回空桶)。
</p>
<p>
注意(顾名思义), <code class="literal">extended_bounds</code><span class="strong strong"><strong>不</strong></span>是过滤桶。

也就是说，如果<code class="literal">extended_bounds.min</code>高于从文档中提取的值，文档仍将指示第一个桶将是什么(<code class="literal">extended_bounds.max</code>和最后一个桶也是如此)。

对于过滤桶，应该使用适当的<code class="literal">from</code>/<code class="literal">to</code>设置将 histogram 聚合嵌套在范围<code class="literal">filter</code>聚合下。
</p>
<p>示例：</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "query" : {
        "constant_score" : { "filter": { "range" : { "price" : { "to" : "500" } } } }
    },
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "extended_bounds" : {
                    "min" : 0,
                    "max" : 500
                }
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/478.console"></div>
<p>
聚合范围时，桶基于返回的文档的值。

这意味着响应可能包含查询范围之外的桶。

例如，如果查询是要查找大于100的值，并且范围从50到150，interval为50，那么该文档将位于3个桶中——50、100和150。

一般来说，最好将查询和聚合步骤看作是独立的——查询负责选择一组文档，然后聚合对这些文档进行分桶，而不考虑它们是如何被选择的。

更多信息和示例参考 <a class="xref" href="search-aggregations-bucket-range-field-note.html" title="Subtleties of bucketing range fields">有关范围字段分桶的提示</a>。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_order_3"></a>order
</h3>
</div></div></div>
<p>
默认情况下，返回的桶按它们的<code class="literal">key</code>升序排序，尽管可以使用<code class="literal">order</code>设置来控制排序行为。

支持与<a class="xref" href="search-aggregations-bucket-terms-aggregation.html#search-aggregations-bucket-terms-aggregation-order" title="排序" rel="nofollow"><code class="literal">terms 聚合</code></a>相同的<code class="literal">order</code>功能。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_offset"></a>Offset
</h3>
</div></div></div>
<p>
默认情况下，桶的键从0开始，然后以<code class="literal">interval</code>的均匀步长继续，例如，如果 interval 是<code class="literal">10</code>，前三个桶(假设其中有数据)将是<code class="literal">[0, 10)</code>、<code class="literal">[10, 20)</code>、<code class="literal">[20, 30)</code>。

可以通过使用<code class="literal">offset</code>选项来移动桶的边界。
</p>
<p>
这可以用一个例子来说明。

如果有10个值在5到14之间的文档，使用间隔<code class="literal">10</code>将产生两个桶，每个桶有5个文档。

如果使用额外的<code class="literal">5</code> 5，将只有一个包含所有10个文档的桶<code class="literal">[5, 15)</code>。
</p>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_response_format"></a>响应格式
</h3>
</div></div></div>
<p>
默认情况下，桶作为有序数组返回。

也可以请求以哈希形式的响应，而不是以桶的键作为键：
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "keyed" : true
            }
        }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/479.console"></div>
<p>响应：</p>
<div class="pre_wrapper lang-console-result">
<pre class="programlisting prettyprint lang-console-result">{
    ...
    "aggregations": {
        "prices": {
            "buckets": {
                "0.0": {
                    "key": 0.0,
                    "doc_count": 1
                },
                "50.0": {
                    "key": 50.0,
                    "doc_count": 1
                },
                "100.0": {
                    "key": 100.0,
                    "doc_count": 0
                },
                "150.0": {
                    "key": 150.0,
                    "doc_count": 2
                },
                "200.0": {
                    "key": 200.0,
                    "doc_count": 3
                }
            }
        }
    }
}</pre>
</div>
</div>

<div class="section">
<div class="titlepage"><div><div>
<h3 class="title">
<a id="_missing_value_15"></a>缺失的值
</h3>
</div></div></div>
<p>
参数<code class="literal">missing</code>定义应该如何处理有缺失值的文档。

默认情况下，它们将被忽略，但也可以将它们视为有一个值。
</p>
<div class="pre_wrapper lang-console">
<pre class="programlisting prettyprint lang-console">POST /sales/_search?size=0
{
    "aggs" : {
        "quantity" : {
             "histogram" : {
                 "field" : "quantity",
                 "interval": 10,
                 "missing": 0 <a id="CO230-1"></a><i class="conum" data-value="1"></i>
             }
         }
    }
}</pre>
</div>
<div class="console_widget" data-snippet="snippets/480.console"></div>
<div class="calloutlist">
<table border="0" summary="Callout list">
<tr>
<td align="left" valign="top" width="5%">
<p><a href="#CO230-1"><i class="conum" data-value="1"></i></a></p>
</td>
<td align="left" valign="top">
<p>字段<code class="literal">quantity</code>中没有值的文档将与值为<code class="literal">0</code>的文档落入同一个桶中。</p>
</td>
</tr>
</table>
</div>
</div>

</div>
<div class="navfooter">
<span class="prev">
<a href="search-aggregations-bucket-global-aggregation.html">« global 聚合</a>
</span>
<span class="next">
<a href="search-aggregations-bucket-iprange-aggregation.html">ip_range 聚合 »</a>
</span>
</div>
</div>

                  <!-- end body -->
                        </div>
                        <div class="col-xs-12 col-sm-4 col-md-4" id="right_col">
                        
                        </div>
                    </div>
                </div>
            </section>
        </div>
    </section>
</div>
<script src="../static/cn.js"></script>
</body>
</html>